package com.wj.ballcat.demo.service.impl;

import com.hccake.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.tangzc.mpe.bind.Binder;
import com.tangzc.mpe.bind.Deeper;
import com.wj.ballcat.demo.converter.DemoUserConverter;
import com.wj.ballcat.demo.mapper.DemoUserMapper;
import com.wj.ballcat.demo.model.dto.DemoUserDTO;
import com.wj.ballcat.demo.model.entity.DemoRole;
import com.wj.ballcat.demo.model.entity.DemoUser;
import com.wj.ballcat.demo.reposity.DemoUserRepository;
import com.wj.ballcat.demo.service.DemoUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 用户服务
 */
@Slf4j
@Service
public class DemoUserServiceImpl  extends ExtendServiceImpl<DemoUserMapper, DemoUser> implements DemoUserService {
	@Resource
	private DemoUserRepository userRepository;

	/**
	 * 根据用户的名字模糊查询所有用户的详细信息
	 */
	@Override
	@Transactional(readOnly = true)
	public List<DemoUserDTO> searchUserByName(String name) {

		// MP的lambda查询方式
		List<DemoUser> userList = userRepository.lambdaQuery()
				.eq(name != null, DemoUser::getUsername, name)
				.list();
		// 关键步骤，指定关联角色数据。如果你打开sql打印，会看到3条sql语句，第一条根据id去User表查询user信息，第二条根据userId去UserRule中间表查询所有的ruleId，第三条sql根据ruleId集合去Rule表查询全部的权限
		Binder.bindOn(userList, DemoUser::getRoles);
		// Deeper为一个深度遍历工具，可以深入到对象的多层属性内部，从而获取全局上该层级的所有对象同一属性
		Binder.bindOn(Deeper.with(userList).inList(DemoUser::getRoles), DemoRole::getMenus);

		return DemoUserConverter.INSTANCE.convertDtos(userList);
	}

	/**
	 * 根据用户的名字模糊查询所有用户的详细信息，等价于上一个查询方式
	 */
	@Override
	@Transactional(readOnly = true)
	public List<DemoUserDTO> searchUserByName2(String name) {

		// 本框架拓展的lambda查询器lambdaQueryPlus，增加了bindOne、bindList、bindPage
		// 显然这是一种更加简便的查询方式，但是如果存在多级深度的关联关系，此种方法就不适用了，还需要借助Binder
		List<DemoUser> userList = userRepository.lambdaQueryPlus()
				.eq(name != null, DemoUser::getUsername, name)
				// 用法一、指定属性关联，只关联身份证号这个字段。
				.bindList(DemoUser::getRoles);
		// 用法二、全关联。
		// .bindList();
		// Deeper为一个深度遍历工具，可以深入到对象的多层属性内部，从而获取全局上该层级的所有对象同一属性
		Binder.bindOn(Deeper.with(userList).inList(DemoUser::getRoles), DemoRole::getMenus);

		return DemoUserConverter.INSTANCE.convertDtos(userList);
	}
}
